home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Mixed Mode Maddness / Emulator / Source / interpret.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-24  |  5.5 KB  |  214 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #include <A4Stuff.h>
  5.  
  6.  
  7. #include "6502.h"
  8. #include "global.h"
  9.  
  10. #include "interpret.h"
  11. #include "debug.h"
  12.  
  13. UInt8 GetOpCodeIndex(UInt8 theByte);
  14. UInt8 GetOpCode(UInt8 theByte);
  15. void PreCacheOpCodes(void);
  16. SInt8 PeekRelative(Ptr myProg, SInt8 howfar);
  17. UInt8 PeekABS(Ptr myProg, SInt8 howfar);
  18.  
  19. UInt8 gCPUCache[sizeof(UInt8) << 3];
  20. static Boolean gInited = false;
  21. typedef pascal void (*MixedModeCallBack)(MixedMode6502DataPtr);
  22.  
  23.  
  24. pascal void main(UInt8* myProg : __A0, MixedModeCallBack theCallBack :__A1);
  25.  
  26.  
  27. pascal void main(UInt8* myProg : __A0, MixedModeCallBack theCallBack : __A1)
  28. {
  29. #pragma unused ( theCallBack)
  30.  
  31.     EnterCodeResource();
  32.   
  33.      gDone = false;
  34.     if (! gInited) {
  35.         InitInterpreter();
  36.     }
  37.  
  38. #define FORMATSTRING    "// PC $%4.4X     SP $%2.2X     A $%2.2X     X $%2.2X     Y $%2.2X   SR %8.8b"
  39.     
  40.     for (gStartofProg = myProg, pc = 0; !gDone;) {
  41.         switch (gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].mode) {
  42. //            case Accumulator:
  43.             case None:
  44.                 Debug("%-s                  "FORMATSTRING,
  45.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  46.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  47.                 break;
  48.  
  49.             case Relative:
  50.                 Debug("%s $%.4X            "FORMATSTRING,
  51.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  52.                      (SInt16)(((SInt16)(pc+2)) + PeekRelative((Ptr)myProg, 1)),
  53.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  54.                 break;
  55.  
  56.             case IndX:
  57.                 Debug("%s ($%.2X,X)          "FORMATSTRING,
  58.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  59.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  60.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  61.                 break;
  62.     
  63.             case ZeroPage:
  64.                 Debug("%s $%.2X              "FORMATSTRING,
  65.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  66.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  67.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  68.                 break;
  69.         
  70.             case Immediate:
  71.                 Debug("%s #$%.2X             "FORMATSTRING,
  72.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  73.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  74.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  75.                 break;
  76.  
  77.             case Absolute:
  78.                 Debug("%s $%.2X%.2X            "FORMATSTRING,
  79.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  80.                      (SInt16)(PeekABS((Ptr)myProg, 2)),
  81.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  82.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  83.                 break;
  84.  
  85.             case IndY:
  86.                 Debug("%s ($%.2X),Y           "FORMATSTRING,
  87.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  88.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  89.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  90.                 break;
  91.  
  92.             case ZeroPageX:
  93.                 Debug("%s $%.2X,X            "FORMATSTRING,
  94.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  95.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  96.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  97.                 break;
  98.  
  99.             case AbsoluteY:
  100.                 Debug("%s $%.2X,Y            "FORMATSTRING,
  101.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  102.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  103.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  104.                 break;
  105.  
  106.             case AbsoluteX:
  107.                 Debug("%s $%.2X%.2X,X           "FORMATSTRING,
  108.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  109.                      (SInt16)(PeekABS((Ptr)myProg, 2)),
  110.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  111.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  112.                 break;
  113.     
  114.             case ZeroPageY:
  115.                 Debug("%s $%.2X,Y           "FORMATSTRING,
  116.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  117.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  118.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc), regP);
  119.                 break;
  120.  
  121.             case Indirect:
  122.                 Debug("%s ($%.2X%.2X)          "FORMATSTRING,
  123.                     gOpCodeBase[gCPUCache[*(myProg + pc)] - 1].name,
  124.                      (SInt16)(PeekABS((Ptr)myProg, 2)),
  125.                      (SInt16)(PeekABS((Ptr)myProg, 1)),
  126.                         (UInt16)pc, (UInt16)sp, (UInt16)regA, (UInt16)regX, (UInt16)regY, *(myProg + pc));
  127.                 break;
  128.  
  129.             default:
  130.                 Debug("What the hell???");
  131.                 break;
  132.         }
  133.  
  134.  
  135.         (*(gOpCodeBase[gCPUCache[*(myProg + pc++)] - 1].fun))();
  136.     }
  137.  
  138.     ExitCodeResource();
  139. }
  140.  
  141. SInt8 PeekRelative(Ptr myProg, SInt8 howfar)
  142. {
  143.     return *(myProg + (( (SInt16)pc)+howfar));
  144. }
  145.  
  146. UInt8 PeekABS(Ptr myProg, SInt8 howfar)
  147. {
  148.     return *(myProg + ((pc)+howfar));
  149. }
  150.  
  151. void InitInterpreter(void)
  152. {
  153.     regA = 0x00;
  154.     regX = 0x00;
  155.     regY = 0x00;
  156.     regP = 0x00;
  157.  
  158.     pc = 0;
  159.     if (gMyMemoryPages == nil)
  160.         gMyMemoryPages = (PagePtr)NewPtrSys(sizeof(Page) * kNumMemPages);
  161.     if (gMyMemoryPages == nil) {
  162.         Debugger();
  163.     }
  164.     gPageZero = (UInt8*)gMyMemoryPages;
  165.      gStack = &gMyMemoryPages[1].mem[0];
  166.  
  167.     if (!gInited)
  168.         PreCacheOpCodes();
  169.     
  170.     gInited = true;
  171. }
  172.  
  173. void PreCacheOpCodes(void)
  174. {
  175.     UInt8 index = 0, opIndex;
  176.  
  177.     for (index = 0; index != 0xFF; index++) {
  178.         opIndex = GetOpCodeIndex(index);
  179.         if (opIndex < gNumOpCodes) {
  180.             gCPUCache[index] = opIndex + 1;
  181.         }
  182.         else {
  183.             gCPUCache[index] = 0;
  184.         }
  185.     }
  186. }
  187.  
  188. UInt8 GetOpCode(UInt8 theByte)
  189. {    
  190.     UInt8 index = GetOpCodeIndex(theByte);
  191.     if (index < gNumOpCodes)
  192.         return gOpCodeBase[index].opCode;
  193.  
  194.     // Crash!
  195.     gDone = true;
  196.     return NOP;
  197. }
  198.  
  199. UInt8 GetOpCodeIndex(UInt8 theByte)
  200. {
  201.     UInt8 count;
  202.     UInt8 tempOpCode;
  203.  
  204.     for (count = 0 ; count < gNumOpCodes; count++) {
  205.         tempOpCode = (UInt8) (gOpCodeBase[count].opCode);
  206.         if (theByte == tempOpCode) {
  207.             return count;
  208.         }
  209.     }
  210.     return gNumOpCodes;
  211. }
  212.  
  213.  
  214.